xcb 截图
通过 xcb_get_image 可以进行截图:
1xcb_get_image_cookie_t
2xcb_get_image (xcb_connection_t *c, // X连接
3 uint8_t format, // 格式
4 xcb_drawable_t drawable, // 要截图的目标,例如窗口,截全屏则为 root 窗口
5 int16_t x, // 截图的起点 x 坐标
6 int16_t y, // 截图的起点 y 坐标
7 uint16_t width, // 截图的宽度
8 uint16_t height, // 截图的高度
9 uint32_t plane_mask); // 色彩通道掩码,例如 0x00ff0000 表示只保留红色通道(小端)1#include <xcb/xcb.h>
2#include <stdio.h>
3#include <stdlib.h>
4
5// 将 BGRX 转换为 RGB
6static uint8_t* BGRX2RGB(const uint8_t* in, int16_t width, int32_t height)
7{
8 uint8_t* out = malloc(width * height *3);
9 for (int16_t y = 0; y < height; y++)
10 {
11 for(int16_t x = 0; x < width; x++)
12 {
13 out[(y*width+x)*3] = in[(y*width+x)*4 + 2];
14 out[(y*width+x)*3 + 1] = in[(y*width+x)*4 + 1];
15 out[(y*width+x)*3 + 2] = in[(y*width+x)*4];
16 }
17 }
18 return out;
19}
20
21int main()
22{
23 // 建立连接
24 xcb_connection_t* conn = xcb_connect(NULL, NULL);
25
26 // 获取 screen
27 const xcb_setup_t* setup = xcb_get_setup(conn);
28 xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
29 xcb_screen_t* screen = iter.data;
30
31 // 获取 root 窗口
32 xcb_window_t root = screen->root;
33
34 // 获取屏幕的宽高
35 int16_t width = 0;
36 int16_t height = 0;
37 {
38 xcb_get_geometry_cookie_t cookie = xcb_get_geometry(conn, root);
39 xcb_get_geometry_reply_t* reply = xcb_get_geometry_reply(conn, cookie, NULL);
40 width = reply->width;
41 height = reply->height;
42 free(reply);
43 }
44
45 // 读取屏幕图像
46 uint8_t* data = NULL;
47 {
48 // XCB_IMAGE_FORMAT_Z_PIXMAP 是 BGRX 格式
49 // 其中 plane_mask 用于过滤不需要的通道,例如 0x00ff0000 表示只保留红色通道(注意小端)
50 xcb_get_image_cookie_t cookie = xcb_get_image(conn, XCB_IMAGE_FORMAT_Z_PIXMAP, root, 0, 0, width, height, UINT32_MAX);
51 xcb_get_image_reply_t* reply = xcb_get_image_reply(conn, cookie, NULL);
52 data = BGRX2RGB(xcb_get_image_data(reply), width, height);
53 free(reply);
54 }
55
56 FILE* fp = fopen("out.ppm", "wb");
57 fprintf(fp, "P6\n");
58 fprintf(fp, "%d %d 255\n", width, height);
59 fwrite(data, width*height*3, 1, fp);
60 fclose(fp);
61
62 free(data);
63 xcb_disconnect(conn);
64
65 return EXIT_SUCCESS;
66}